import mime from 'mime'
import axios from 'axios'
import { saveAs } from 'file-saver'

/**
 * @description 返回以单位表示的文件大小
 * @param {number} size 文件比特大小
 * @return string 以单位表示的文件大小
 */
export function transformSize(size: number): string {
  const unitList = [
    { size: 1, name: 'B' },
    { size: 1024, name: 'KB' },
    { size: 1024 * 1024, name: 'MB' },
    { size: 1024 * 1024 * 1024, name: 'GB' },
    { size: 1024 * 1024 * 1024 * 1024, name: 'TB' }
  ]
  let realSize = '0B'
  unitList.forEach((unit, index) => {
    if (
      size >= unit.size &&
      (index + 1 >= unitList.length || size < unitList[index + 1].size)
    ) {
      realSize = `${(size / unit.size).toFixed(1)}${unit.name}`
      return
    }
  })
  return realSize
}

/**
 * @description 判断文件类型是否正确
 * @param {string} fileType 如：'image/png'
 * @param {Array<string>} allowedFileTypes  如：['image/png'] / ['image/*'] / ['.png'] / ['*']
 * @return boolean 文件类型是否正确
 */
export function fileTypeCorrect(
  fileType: string,
  allowedFileTypes: Array<string>
): boolean {
  if (allowedFileTypes.length === 0 || allowedFileTypes.includes('*'))
    return true

  const oneCorrect = (fileType, allowedFileType) => {
    if (allowedFileType.includes('.')) {
      return (
        mime.getExtension(fileType) === allowedFileType.replace('.', '').trim()
      )
    } else if (allowedFileType.includes('/*') && fileType.includes('/')) {
      return (
        fileType.split('/')[0].trim() === allowedFileType.split('/')[0].trim()
      )
    } else
      return mime.getExtension(fileType) === mime.getExtension(allowedFileType)
  }

  return allowedFileTypes.some((allowedFileType) =>
    oneCorrect(fileType, allowedFileType)
  )
}

// 验证是否为blob格式
export async function blobValidate(data) {
  try {
    const text = await data.text()
    JSON.parse(text)
    return false
  } catch (error) {
    return true
  }
}

/**
 * 文件下载 -- blob流下载
 * @param fileOption
 *  - url 文件路径
 *  - params 请求参数
 *  - filename 文件名
 */
export function fileDownload(fileOption: {
  url: string
  filename: string
  params?: any
}) {
  return axios
    .get(fileOption.url, {
      params: fileOption.params,
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      responseType: 'blob'
    })
    .then(async ({ data }) => {
      const isBlob = await blobValidate(data)
      if (isBlob) {
        const blob = new Blob([data])
        saveAs(blob, fileOption.filename)
      } else {
        const resText = await data.text()
        const rspObj = JSON.parse(resText)
        window['$message'].error(`错误：${rspObj.message || '下载文件失败！'}`)
      }
    })
    .catch((r) => {
      console.error(r)
      window['$message'].error('下载文件失败！')
    })
}

/**
 * 文件批量下载 -- blob流下载
 * @param fileOptionList
 *
 */
export function fileDownloadBatch(
  fileOptionList: { url: string; filename: string; params?: any }[]
) {
  for (let index = 0; index < fileOptionList.length; index++) {
    const fileOption = fileOptionList[index]
    fileDownload(fileOption)
  }
}

/**
 * 获取文件名
 * @param url 文件地址
 * @returns
 */
export function getFilename(url: string) {
  const filename =
    decodeURI(url)?.match(/filename%3D"(\S*)"/)?.[1] || Date.now()
  if (!filename) {
    throw new Error('文件名不存在!')
  }
  return filename as string
}
